home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group92c.txt
/
000024_icon-group-sender _Mon Oct 19 14:17:00 1992.msg
< prev
next >
Wrap
Internet Message Format
|
1993-01-04
|
4KB
Received: by cheltenham.cs.arizona.edu; Mon, 19 Oct 1992 12:35:02 MST
Message-Id: <199210191919.AA25581@optima.cs.arizona.edu>
From: nowlin@iwtqg.att.com
Date: Mon, 19 Oct 92 14:17 CDT
To: att!cs.arizona.edu!icon-group
Subject: Re: sorting on multiple fields
Status: R
Errors-To: icon-group-errors@cs.arizona.edu
There must be something like this in the IPL but here's what I've used for
years if I wanted to sort a list of records by various fields. It could
also be used for lists of lists but the variable names would make that a
little confusing.
Jerry Nowlin
----------------------------------> cut here <--------------------------------
# This example program is to illustrate the recsort() procedure. It sorts
# a UNIX style password file. The arguments to the program should be the
# fields in each password entry to sort on in order of precedence. The
# program has a built-in limit of the first 20 entries in the password file
# but it can be removed to test the program on the whole password file.
# Notice that the UID and GID fields are now forced to be numeric. Sorts
# on these fields will work accordingly.
record passwd(name,pass,uid,gid,info,logdir,shell)
procedure main(args)
if *args = 0 then stop("I need a numeric record index to sort on")
users := []
in := open("/etc/passwd","r")
every line := !in\20 do line ? {
user := passwd()
user.name := tab(upto(':')) & move(1)
user.pass := tab(upto(':')) & move(1)
user.uid := numeric(tab(upto(':'))) & move(1)
user.gid := numeric(tab(upto(':'))) & move(1)
user.info := tab(upto(':')) & move(1)
user.logdir := tab(upto(':')) & move(1)
user.shell := tab(0)
put(users,user)
}
close(in)
write("UNSORTED: ",image(users)," ",image(users[1]))
every user := !users do write( user.name,":",
user.pass,":",
user.uid,":",
user.gid,":",)
#user.info,":",
#user.logdir,":",
#user.shell)
stuff := recsort(users,args)
write("\nSORTED: ",image(stuff)," ",image(stuff[1]))
every user := !stuff do write( user.name,":",
user.pass,":",
user.uid,":",
user.gid,":",)
#user.info,":",
#user.logdir,":",
#user.shell)
end
# Sort the list of records passed in recs by the list of field indexes
# passed in keys. A field index must be numeric and refer to one of the
# fields in the record type being sorted. If a numeric field index is
# negative the positive value will be used but the sorting done on that
# field will be in reverse order. A sorted list of records is returned.
procedure recsort(recs,keys)
# Initialize a temporary table.
tempt := table()
# Get a sorting key.
key := get(keys)
# If the key is negative sort in reverse order.
if key < 0 then {
key := -key
getpair := pull
} else getpair := pop
# Take every record in the recs list and add it to the table.
every rec := !recs do
# Each index to the table is a different sorting key. To
# avoid losing records which have identical sorting keys
# each value in the table must be a list of the records
# that are indexed by a given sorting key.
(/tempt[rec[key]] := [ rec ]) | put(tempt[rec[key]],rec)
# Sort the table by the indexes (sorting keys).
templ := sort(tempt,1)
# Initialize a new records list.
newrecs := []
# Take apart the pairs of lists generated by the sort.
while pair := getpair(templ) do {
# If there is more than one record in this value list and
# there are additional keys to sort on recursively sort
# this value list with the remaining keys.
if *pair[2] > 1 & *keys > 0 then
pair[2] := recsort(pair[2],copy(keys))
# Add each record from the value list to the temporary list.
every put(newrecs,!pair[2])
}
# Return the new sorted list of records.
return newrecs
end